package com.yqr.oss;


import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;

import java.text.MessageFormat;

/**
 * OSS STS服务临时授权
 */
public class OSSSTSKit {
    /**
     * 当前 STS API 版本
     */
    private static final String STS_API_VERSION = "2015-04-01";
    
    /**
     * 目前只有"cn-hangzhou"这个region可用, 不要使用填写其他region的值
     */
    public static String REGION_CN;
    
    /**
     * 只有 RAM用户（子账号）才能调用 AssumeRole 接口
     * 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
     * 请首先在RAM控制台创建一个RAM用户，并为这个用户创建AccessKeys
     */
    public static String STS_ACCESS_KEY_ID;
    public static String STS_ACCESS_KEY_SECRET;
    public static String BUCKET;
    /**
     * RoleArn 需要在 RAM 控制台上获取
     */
    public static String STS_ROLE_ARN;
    /**
     * 过期时间 900s 15分钟
     */
    public static Long STS_DURATION_SECONDS;
    public static String ENDPOINT;
    public static String INTERNAL_ENDPOINT;
    
 
    
    /**
     * OSS STS返回有效的访问凭证
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @param roleArn
     * @param roleSessionName
     * @param policy
     * @param durationSeconds
     * @param protocolType
     * @return
     * @throws ClientException
     */
    private static AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret,
            String roleArn, String roleSessionName, String policy,
            Long durationSeconds, ProtocolType protocolType) throws ClientException {
        // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
        IClientProfile profile = DefaultProfile.getProfile(REGION_CN, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        // 创建一个 AssumeRoleRequest 并设置请求参数
        final AssumeRoleRequest request = new AssumeRoleRequest();
        request.setVersion(STS_API_VERSION);
        request.setMethod(MethodType.POST);
        request.setProtocol(protocolType);
        request.setRoleArn(roleArn);
        request.setRoleSessionName(roleSessionName);
        request.setPolicy(policy);
        request.setDurationSeconds(durationSeconds);
        // 发起请求，并得到response
        return client.getAcsResponse(request);
    }
    
    /**
     * OSS STS返回有效的访问凭证
     *
     * @param roleSessionName RoleSessionName 是临时Token的会话名称，自己指定用于标识你的用户，主要用于审计，或者用于区分Token颁发给谁
     *                        ，但是注意RoleSessionName的长度和规则，不要有空格，只能有'-' '_' 字母和数字等字符，具体规则请参考API文档中的格式要求
     * @return
     * @throws ClientException
     */
    public static AssumeRoleResponse assumeRole(String roleSessionName,String fileUrl) throws ClientException {
        String STS_POLICY = getPolicy(BUCKET,fileUrl);
        return OSSSTSKit.assumeRole(STS_ACCESS_KEY_ID, STS_ACCESS_KEY_SECRET, STS_ROLE_ARN, roleSessionName, STS_POLICY
                , STS_DURATION_SECONDS, ProtocolType.HTTPS);
    }
    
    /**
     * 获取 policy
     *
     * @param bucketName
     * @return
     */
    private static String getPolicy(String bucketName,String fileUrl) {
        return MessageFormat.format("'{'\n" +
                "    \"Statement\": [\n" +
                "        '{'\n" +
                "            \"Action\": [\n" +
                "                \"oss:GetObject\",\n" +
                "                \"oss:PutObject\",\n" +
                "                \"oss:ListParts\",\n" +
                "                \"oss:DeleteObject\",\n" +
                "                \"oss:AbortMultipartUpload\",\n" +
                "                \"oss:ListObjects\"\n" +
                "            ], \n" +
                "            \"Resource\": [\n" +
                "                \"acs:oss:*:*:{0}/{1}\"\n" +
                "            ], \n" +
                "            \"Effect\": \"Allow\"\n" +
                "        '}'\n" +
                "    ],\n" +
                "    \"Version\": \"1\"\n" +
                "'}'",bucketName,fileUrl);
    }
}

